//
//  YLStoreKitV1Manager.swift
//  YLPaymentKit
//
//  Created by changhe on 2025/4/12.
//

import Foundation
import StoreKit
import ObjectiveC

/// StoreKit 1管理器
/// 处理StoreKit 1 API的内购功能
/// 注意：虽然StoreKit 1在iOS 15及以上版本中已有更新的StoreKit 2 API，但StoreKit 1仍然可用
public class YLStoreKitV1Manager: NSObject, SKPaymentTransactionObserver, SKProductsRequestDelegate, YLStoreKitManagerProtocol {
    
    // MARK: - 类型定义
    
    /// 商品请求完成回调
    public typealias ProductsRequestCompletion = (Result<[SKProduct], Error>) -> Void
    
    // MARK: - 属性
    
    /// 商品缓存
    private var products: [String: SKProduct] = [:]
    
    /// 商品请求
    private var productsRequest: SKProductsRequest?
    
    /// 商品请求完成回调
    private var productsCompletion: ProductsRequestCompletion?
    
    /// 当前支付回调
    private var paymentCallback: ((YLPaymentResult) -> Void)?
    
    /// 当前恢复购买回调
    private var restoreCallback: ((YLPaymentResult) -> Void)?
	
	// 未完成交易的回调
	var unfinishedTransactionsCallBack: (([YLTransactionInfo])-> Void)?
	
    // MARK: - YLStoreKitManagerProtocol 实现
    
    /// 是否可用
    public var isAvailable: Bool {
        return SKPaymentQueue.canMakePayments()
    }
	
    /// 获取商品信息
    public func fetchProducts(productIds: [String], completion: @escaping (Result<[Any], Error>) -> Void) {
        guard !productIds.isEmpty else {
            completion(.failure(YLPaymentError.invalidParameters))
            return
        }
        
        // 将泛型回调转换为具体类型回调
        self.productsCompletion = { result in
            switch result {
            case .success(let products):
                completion(.success(products))
            case .failure(let error):
                completion(.failure(error))
            }
        }
        
        // 创建商品请求
        let request = SKProductsRequest(productIdentifiers: Set(productIds))
        request.delegate = self
        request.start()
        
        self.productsRequest = request
    }
    
    /// 完成交易
    public func finishTransaction(_ transaction: Any) {
        if let transaction = transaction as? SKPaymentTransaction {
            SKPaymentQueue.default().finishTransaction(transaction)
			YLUnfinishedTransactionsCache.removeRecord(transaction: transaction)
        }
    }
    
    // MARK: - 初始化
	override init() {
        super.init()
		SKPaymentQueue.default().add(self)
    }
    
    // MARK: - 公共方法
    
    /// 购买商品
    public func purchase(productId: String, orderId: String, completion: @escaping (YLPaymentResult) -> Void) {
      
        self.paymentCallback = completion
        
        guard SKPaymentQueue.canMakePayments() else {
            completion(.failure(.sdkNotAvailable))
            return
        }
        
        if let product = products[productId] {
            purchaseProduct(product, orderId: orderId)
            return
        }
        
        fetchProducts(productIds: [productId]) { [weak self] result in
            guard let self = self else { return }
            
            switch result {
            case .success(let products):
                guard let product = products.first as? SKProduct else {
                    completion(.failure(.productNotFound))
                    return
                }
                
                self.purchaseProduct(product, orderId: orderId)
                
            case .failure(let error):
                if let paymentError = error as? YLPaymentError {
                    completion(.failure(paymentError))
                } else {
                    completion(.failure(.other(error.localizedDescription)))
                }
            }
        }
    }
    
    /// 恢复购买
    public func restorePurchases(completion: @escaping (YLPaymentResult) -> Void) {
        // 保存回调
        self.restoreCallback = completion
        
        SKPaymentQueue.default().restoreCompletedTransactions()
    }
     
	public func checkUnfinishedTransactions(completHandler: (([YLTransactionInfo])-> Void)?) {
		unfinishedTransactionsCallBack = completHandler
	}
	
    // MARK: - 私有方法
    
    /// 购买商品
    private func purchaseProduct(_ product: SKProduct, orderId: String) {
        let payment = SKMutablePayment(product: product)
        
        if !orderId.isEmpty {
            // 关联订单ID到 applicationUsername（这是 StoreKit 1 中的标准方式）
			payment.applicationUsername = YLOrderUUIDTransformer.toUUID(orderId)
            print("[YLPaymentKit] 设置订单ID到applicationUsername: \(orderId)")
        } else {
            print("[YLPaymentKit] 警告: 订单ID为空")
        }
        
        SKPaymentQueue.default().add(payment)
    }
    
    // MARK: - SKProductsRequestDelegate
    
    @available(iOS, deprecated: 18.0, message: "使用Product.products(for:)代替")
    public func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
        let products = response.products
        
        // 缓存商品
        for product in products {
            self.products[product.productIdentifier] = product
        }
        
        // 调用回调
        productsCompletion?(.success(products))
        
        // 清理状态
        productsCompletion = nil
        productsRequest = nil
    }
    
    @available(iOS, deprecated: 18.0, message: "使用Product.products(for:)代替")
    public func request(_ request: SKRequest, didFailWithError error: Error) {
        productsCompletion?(.failure(error))
        
        // 清理状态
        productsCompletion = nil
        productsRequest = nil
    }
    
    // MARK: - SKPaymentTransactionObserver
    
    @available(iOS, deprecated: 18.0, message: "使用Transaction.updates代替")
    public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        for transaction in transactions {
			
            switch transaction.transactionState {
            case .purchased:
                // 购买成功
                handlePurchasedTransaction(transaction)
                
            case .failed:
                // 购买失败
                handleFailedTransaction(transaction)
                
            case .restored:
                // 恢复购买
                handleRestoredTransaction(transaction)
                
            case .deferred, .purchasing:
                // 交易中或延迟，不处理
                break
                
            @unknown default:
                break
            }
        }
		
		let unhandledTransactions = transactions.filter { $0.transactionState != .purchasing }
		
		let resultUnfinishedTransactions = processTransactions(unhandledTransactions, on: queue)
		
		if !resultUnfinishedTransactions.isEmpty {
			unfinishedTransactionsCallBack?(resultUnfinishedTransactions)
			unfinishedTransactionsCallBack = nil
		}
    }
    
    private func handlePurchasedTransaction(_ transaction: SKPaymentTransaction) {
		YLUnfinishedTransactionsCache.addRecord(transaction: transaction)
        paymentCallback?(.success(getPaymentResultData(transaction: transaction)))
        paymentCallback = nil
    }
    
    private func handleFailedTransaction(_ transaction: SKPaymentTransaction) {
        // 完成交易
        SKPaymentQueue.default().finishTransaction(transaction)
        
        if let error = transaction.error as? SKError {
            if error.code == .paymentCancelled {
                // 用户取消
                paymentCallback?(.cancel)
            } else {
                // 其他错误
                let errorMessage = "交易失败：\(error.localizedDescription)"
                paymentCallback?(.failure(.other(errorMessage)))
            }
        } else {
            // 未知错误
            paymentCallback?(.failure(.unknownError))
        }
        
        paymentCallback = nil
    }
    
    private func handleRestoredTransaction(_ transaction: SKPaymentTransaction) {
		restoreCallback?(.success(getPaymentResultData(transaction: transaction)))
    }
    
    @available(iOS, deprecated: 18.0, message: "使用AppStore.sync()代替")
    public func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
        // 恢复购买完成
        if restoreCallback != nil {
            // 如果没有恢复的交易，也返回成功
            if queue.transactions.filter({ $0.transactionState == .restored }).isEmpty {
                // 创建结构化的结果数据
                let resultData = YLPaymentResultData(
                    orderId: "",
                    transactionId: "",
                    productId: nil,
                    transactionDate: Date(),
                    originalTransactionId: nil,
					rawInfo: [:]
                )
                
                restoreCallback?(.success(resultData))
            }
        }
        
        restoreCallback = nil
    }
    
    @available(iOS, deprecated: 18.0, message: "使用AppStore.sync()代替")
    public func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: Error) {
        // 恢复购买失败
        restoreCallback?(.failure(.other(error.localizedDescription)))
        restoreCallback = nil
    }
} 


extension YLStoreKitV1Manager {
	
	fileprivate func getPaymentResultData(transaction: SKPaymentTransaction)-> YLPaymentResultData {
		// 提取信息
		let orderId = transaction.payment.applicationUsername ?? ""

		let info = YLTransactionInfo(skTransaction: transaction)
		
		let resultData = YLPaymentResultData(
			orderId: YLOrderUUIDTransformer.fromUUID(orderId),
			transactionId: transaction.transactionIdentifier ?? "",
			productId: transaction.payment.productIdentifier,
			transactionDate: transaction.transactionDate ?? Date(),
			originalTransactionId: transaction.original?.transactionIdentifier,
			transactionInfo: info,
			rawInfo: transaction
		)
		
		// 打印订单ID信息以便于调试
		if let username = transaction.payment.applicationUsername {
			debugPrint("[YLPaymentKit] 成功处理交易，订单ID(applicationUsername): \(username)")
		} else {
			debugPrint("[YLPaymentKit] 成功处理交易，未找到订单ID")
		}
		return resultData
	}
	
	
	func processTransactions(_ transactions: [SKPaymentTransaction], on paymentQueue: SKPaymentQueue) -> [YLTransactionInfo] {

		var purchases: [YLTransactionInfo] = []

		for transaction in transactions {

			let transactionState = transaction.transactionState

			if transactionState != .purchasing {
				
				var purchase = YLTransactionInfo(skTransaction: transaction)

				let ownOrderId = YLUnfinishedTransactionsCache.findOwnOrderId(for: transaction)
				
				purchase.orderId = ownOrderId
				
				purchases.append(purchase)

				if transactionState == .failed {
					debugPrint("Finishing transaction for payment \"\(transaction.payment.productIdentifier)\" with state: \(transactionState)")
					paymentQueue.finishTransaction(transaction)
				}
			}
		}

		return purchases
	}
}
